-- Author: shunguo.chen
-- Date: 2016-06-17 11:42:45
--
-- IMRoomController
--

local IMRoomView = import("..views.IMRoomView")
local IMOpenBtn = import("..views.renders.IMOpenBtn")
local Equip = require("app.public.dao.Equip")
local Mount = require("app.public.dao.Mount")
local Partner = require("app.public.dao.Partner")

local fileName = string.getModeName(...)
local ClassRef = class(fileName, app.mvc.ControllerBase)

function ClassRef:ctor(params)
	self.super.ctor(self, params)

end

function ClassRef:init()
	self._model = app:getInst("IMModel")

	self._curChannelIdx = 1
	self._curTarget = nil

	-- 上次关闭界面之后，收到的招募信息数目
	self._newTeamreqMsgNum = 0

	self._textReplaceDict = {}
	self._textRemoveDict = {}

	--当前在播放录音的IMMsgRender
	self._voicePlayRender = nil

	self._appendMsgCache = nil
	self._isAutoScrollLock = false

	--自动播放消息缓存
	self._autoPlayMsgCache = {}

	-- openBtn的缓存
	self._openBtnCache = {}
	setmetatable(self._openBtnCache, {__mode = "kv"})

	self._bagHandler = UD.bag:onChanged(handler(self._model, self._model.updateItem))
    self._equipHandler = UD:onChanged("equip",handler(self._model, self._model.updateEquip))
	self._mountHandler = UD:onChanged("mount",handler(self._model, self._model.updateMount))
	self._achieveHandler = UD:onChanged("achievement",handler(self._model, self._model.updateAchievement))
	self._fameHandler = UD:onChanged("fame",handler(self._model, self._model.updateFame))
	self._playerHandler = UD.player:onChanged(handler(self._model, self._model.updatePlayer))
	self._walletHandler = UD:onChanged("wallet", handler(self._model, self._model.updatePlayer))
end

function ClassRef:removeListeners()
	self.super.removeListeners(self)
	UD:unChanged("equip", self._equipHandler)
	UD:unChanged("mount", self._mountHandler)
	UD:unChanged("achievement", self._achieveHandler)
	UD:unChanged("fame", self._fameHandler)
	UD.bag:unChanged(self._bagHandler)
	UD.player:unChanged(self._playerHandler)
	UD:unChanged("wallet", self._walletHandler)
end

function ClassRef:listEvent()
    return {
	    -- "OnGameConnected",
	    "onReconnectSuccessed",
	    "im_newMessages",
	    "QuitGuild",
	    "GuildUpdate",
	    "OnGuildCreated",
	    "onAddFriend",
	    "onRemoveFriend",
	    "onAddBlack",
	    "onRemoveBlack",
	    "onCreateTeam",
	    "onTeamUpdate",
	    "onIntoMap",
	    "onRecordPhaseChange",
	    "addSystemLog",
		"onTeamDataChangedNotify",
		"onSettingImChannelInfo",
		"refreshIMAllChannel",
		"onTeamSettingUpdate",
		"SendGuildRecruit",
	}
end

function ClassRef:onEvent(eventName, ...)
	local data = ...
	if eventName == "OnGameConnected" then

	elseif eventName == "onReconnectSuccessed" then
		self._model:onReconnectSuccessed()
		self:hideView()
	elseif eventName == "onRecordPhaseChange" then
		local phase = ...
		if phase == Enums.IMRecordPhase.Start then
			if self:isViewVisible() then
				self._view:hidePanel()
			end
		elseif phase == Enums.IMRecordPhase.End then

		end
	elseif eventName == "im_newMessages" then
		self:appendNewMsgs(data)
	elseif eventName == "QuitGuild" then
		self._model:updateGuild()
		self._model:addSystemMsg("leaveguild", data)
	elseif eventName == "GuildUpdate" then
		self._model:updateGuild( data )
	elseif eventName == "OnGuildCreated" then
		self._model:addSystemMsg("creatguild", data)
	elseif eventName == "onAddFriend" then
		self._model:addSystemMsg("followplayer", data)
	elseif eventName == "onRemoveFriend" then
		self._model:addSystemMsg("deletefriend", data)
	elseif eventName == "onAddBlack" then
		self._model:addSystemMsg("ignoreplayer", data)
	elseif eventName == "onRemoveBlack" then
		self._model:addSystemMsg("ignorecancel", data)
	elseif eventName == "onTeamUpdate" then
		self._model:updateTeam(data)
	elseif eventName == "onIntoMap" then
		self._model:addSystemMsg("arrivemap", {data.mapName})
	elseif eventName == "addSystemLog" then
		self._model:addSystemMsg(...)
	elseif eventName == "onTeamDataChangedNotify" then
		self._model:addSystemMsg( data )
	elseif eventName == "onSettingImChannelInfo" then
		self._model:SettingImChannelInfo(...)
	elseif eventName == "refreshIMAllChannel" then
		self:_refreshMsgList()
	elseif eventName == "onCreateTeam" then
		-- 创建队伍，如果是自动招募，发送组队招募信息
		self:_checkNeedTeamReq()
	elseif eventName == "onTeamSettingUpdate" then
		-- 队伍设置变化，如果是自动招募，发送组队招募信息
		self:_checkNeedTeamReq()
	elseif eventName == "SendGuildRecruit" then
		-- 发送公会招募信息
		self:sendGuildRecruit(data.desc, data.guildId)
	end
end

-- 获得IMOpenBtn
function ClassRef:getIMOpenBtn()
	local openBtn = IMOpenBtn.create()
	openBtn:setName("IMOpenBtn")
	openBtn:onBtnClick(function()
		self:showView()
	end)
	self._openBtnCache[openBtn] = 1
	return openBtn
end

function ClassRef:showView(data)
	if cc.isDead(self._view) then
		self._view = IMRoomView.new(app.mvc.VIEWTYPE_NORMAL)
		self._view:onHideView(handler(self, self.hideView))
		self._view:onListScroll(handler(self, self.onListScroll))
		self._view:onOperate(handler(self, self.onOperate))
		self._view:onBoxSwitch(handler(self, self.onBoxSwitch))
		self._view:onChannelSwitch(handler(self, self.onChannelSwitch))
		self:addChild(self._view)
	end
	local channelIdx = (data ~= nil) and data or self._curChannelIdx -- 从私聊右下角提示进入聊天界面
	self._view:show()
	self._view:switchChannel(channelIdx)

	--self._textReplaceDict = {}
	--self._textRemoveDict = {}

	-- print("self._newTeamreqMsgNum", self._newTeamreqMsgNum)
	if channelIdx == 7 then
		self._view:setTeamreqTipVisible(false)
	else
		self._view:setTeamreqTipVisible(self._newTeamreqMsgNum > 0)
	end
	self._newTeamreqMsgNum = 0

	app:sendMsg("TeamModel", "reqPostPlayerState", Constant.FUNC_TYPE_CHAT)
end

function ClassRef:hideView()
	if not self:isViewVisible() then return end
	self._view:hide(function()
		if not BattleManager:isBattle() and not UIHandler:isHaveUI() then
			app:sendMsg("IMSimpleController", "showView")

			-- 触发引导
			UIHandler:checkDesktopGuide()
			UIHandler:postDesktopState()
		end

		-- 显示IMOpenBtn
		for k,v in pairs(self._openBtnCache) do
			if not cc.isDead(k) then
				k:setVisible(true)
			else
				self._openBtnCache[k] = nil
			end
		end
	end)
	self:stopPlay()
end

-- info.uid = user.uid
-- info.name = user.name
-- info.level = user.level
-- info.classID = user.classID
-- info.raceID = user.raceID
-- info.gender = user.gender
-- info.hairID = user.hairID
-- info.faceID = user.faceID
-- info.hairColorID = user.hairColorID
function ClassRef:speakToTarget(target)
	-- dump(target, "IMRoomController:speakToTarget()")
	assert(target)
	target.sessionType = im.SessionType.P2p
	self._model:addTargetList(target)
	self.isSpeakToTarget = true --我主动跟某人聊天，要切换选中目标

	if not self:isViewVisible() then
		self._curChannelIdx = 6
		self._model:setCurChannelIdx(self._curChannelIdx)
		self:showView()
	else
		if self._curChannelIdx ~= 6 then
			self._curChannelIdx = 6
			self._model:setCurChannelIdx(self._curChannelIdx)
			self._view:switchChannel(self._curChannelIdx)
		else
			self._curTarget = target
			self:insertPriTarget(target)
		end
	end
end

--key = channelId(string) or channelIdx(number)
function ClassRef:speakToChannel(key)
	-- print("IMRoomController:speakToChannel() key", key)
	if type(key) == "string" then
		key = self._model:getChannelIdxById(key)
	end
	self._curChannelIdx = key or self._curChannelIdx
	self._model:setCurChannelIdx(self._curChannelIdx)
	self:showView()
end

-- 发送招募消息到 组队频道
-- option = TeamRecruitInfoVo
function ClassRef:sendTeamReq(teamId, targetId, option)
	-- print("sendTeamReq teamId", teamId)
	-- dump(option, "sendTeamReq option")
	local text = option:getPulishWords()
	text = "[t|"..text.. "|" .. teamId ..  "|" .. targetId .. "]"
	local target = self._model:getChannelTarget("teamreq")

	-- print("sendTeamReq text", text)
	if option:hasAudio() then
		local param = {fileId=option.memoAudio, duration=option.audioDuration, audioText=text}
		self:sendAudioMessage(param, target)
	else
		self:sendTextMessage(text, target)
	end
end

-- 创建队伍和变更队伍设置时(我的队伍)
function ClassRef:_checkNeedTeamReq()
	local team = app:sendMsg("TeamModel", "getTeam")
	if not team then return end
	if not team:isMyTeam() then return end

	local target = team:getTeamTargetVo()
	-- 1.有目标 2.自动招募 3.人数未满 发送招募消息
	if target and team:isAutoRecruit() and team:getMemberNum() < target:getMaxNum() then
		local teamId = team:getTeamId()
		local recruitInfoVo = team:getTeamSetting()
		self:sendTeamReq(teamId, target:getId(), recruitInfoVo)
	end
end

-- 分享道具到聊天输入框
-- puid 用于拍卖行装备分享，拍卖人的uid
function ClassRef:shareItem(tipsType, tid, uid, puid)
	if cc.isAlive(self._view) then
		-- 当前频道不能文本输入时，如果是语音输入切换到文本输入，如果不是切换到世界频道
		if not self._view:canInputWord() then
			if self._view:canInputVoice() then
				self._view:setInputWord()
			else
				self._curChannelIdx = 2
				self._model:setCurChannelIdx(self._curChannelIdx)
			end
		end
	else
		-- 默认分享到世界频道
		self._curChannelIdx = 2
		self._model:setCurChannelIdx(self._curChannelIdx)
	end
	if not self:isViewVisible() then self:showView() end

	printf("tipsType = %s, id = %s", tostring(tipsType), tostring(tid))
	local data = self._model:getShareData(tipsType, tid, uid, puid)
	if data then
		self:appendWords(data.textShow, data.textSend, data.replace)
	else
		display.pushToastDebug(L("lua_code_text_239"))
	end
end

-- 发送公会宣言到无公会玩家的招募频道
function ClassRef:sendGuildRecruit(str, guildId)
	local text = string.trim(str)
	if string.find(str, "[\t\n\r]") then
		text = string.gsub(str, "[\t\n\r]", "") -- 去掉换行
	end
	text = text .. "<br />[g|" .. "text_11400015" .. "|" .. guildId .. "]"
	local target = self._model:getChannelTarget("teamreq")
	
	self:sendTextMessage(text, target)
end

-------------------------------------
function ClassRef:appendNewMsgs(msgs)
	if msgs == nil or #msgs == 0 then return end

	if not self:isViewVisible() then
		-- view不可见时，累计组队招募的数量
		for _,msg in ipairs(msgs) do
			if msg.channelId == "teamreq" then
				self._newTeamreqMsgNum = self._newTeamreqMsgNum + 1
			end
		end
		return
	end

	-- print("IMRoomController._isAutoScrollLock", self._isAutoScrollLock)

	if not self._isAutoScrollLock then
		for i,v in ipairs(msgs) do
			self:appendNewMsg(v)
		end
		self._appendMsgCache = nil
		self._view:scrollToNew()
	else
		local isOut = false
		for i,msg in ipairs(msgs) do
			isOut = msg.isOutgoingMsg
			self:addAppendMsgCache(msg)
		end
		-- 有自己发送出去的消息，取消锁屏，直接滚动到最新
		if isOut then
			self:setAutoScrollLock(false)
		end
	end
end

function ClassRef:updateMessage(msg)
	if not self:isViewAlive() then return end
	local items = self._view:getMsgItems()
	for i,item in ipairs(items) do
		if item:getData() == msg then
			item:setData(msg)
			break
		end
	end
end

function ClassRef:showTip(result, param)
	if not self:isViewAlive() then return end
	if param.what == "equip" then
		local equip = result.equip
		if equip then
			local equipData = Equip.new()
			equipData:read(equip)
			local data = {
				itemId=equipData.tid,
				tipsType=Enums.TipsType.equip,
				dataTemp=equipData,
				showPreviewBtn=true
			}
			self:openFloatTip(data, nil, display.height*1/4)
		end
	end
end

function ClassRef:updateWorldOpen()
	if not self:isViewAlive() then return end
	if self._curChannelIdx == 1 or self._curChannelIdx == 2 then
		self._view:switchChannel(self._curChannelIdx)
	end
end

--------------------------------------- view logic ---------------------------------------
function ClassRef:setAutoScrollLock(b)
	if self._isAutoScrollLock ~= b then
		-- print("setAutoScrollLock", b)
		self._isAutoScrollLock = b
		if not b then
			if self._appendMsgCache and #self._appendMsgCache > 0 then
				-- 缓存的消息太多了，直接重新刷新
				if #self._appendMsgCache <= 20 then
					for i,msg in ipairs(self._appendMsgCache) do
						local render = self._view:addNewMsgItem()
						render:setData(msg)
						render:onClickLink(handler(self, self.onClickLink))
					end
					self._view:scrollToNew()
				else
					self:_refreshMsgList()
				end
			end
			self._appendMsgCache = nil
			self._view:refreshNewMsg(0)
		end
	end
end
function ClassRef:onListScroll(sender, eventType)
	if eventType == ccui.ScrollviewEventType.scrollToTop then
		-- print("IMRoomView scroll scrollToTop")
	elseif eventType == ccui.ScrollviewEventType.scrollToBottom then
		-- print("IMRoomView scroll scrollToBottom")
	elseif eventType == ccui.ScrollviewEventType.bounceTop then
		-- print("IMRoomView scroll bounceTop")
		local msgs = self._model:getRestChannelData(self._curChannelIdx)
		if msgs then
			for i,msg in ipairs(msgs) do
				if self:isShowMessage(msg) then
					local render = self._view:addOldMsgItem()
					if render then
						hasAdd = true
						render:setData(msg)
						render:onClickLink(handler(self, self.onClickLink))
					else
						break
					end
				end
			end
		end
	elseif eventType == ccui.ScrollviewEventType.bounceBottom then
		-- print("IMRoomView scroll bounceBottom")
		self:setAutoScrollLock(false)
	elseif eventType == ccui.ScrollviewEventType.autoStop then
		-- print("IMRoomView scroll autoStop")
		local size = sender:getContentSize()
		local innerSize = sender:getInnerContainerSize()
		local posY = sender:getInnerContainer():getPositionY()
		local posMaxY = size.height - innerSize.height
		local posMinY = 0
		-- print("posY", posY)
		-- print("posMinY", posMinY)
		-- print("posMaxY", posMaxY)
		-- dump(size, "size")
		-- dump(innerSize, "innerSize")

		if math.abs(posY - posMinY) > 1 then
			self:setAutoScrollLock(true)
		else
			self:setAutoScrollLock(false)
		end
	elseif eventType == ccui.ScrollviewEventType.scrolling then
		-- print("IMRoomView scroll scrolling")
	end
end

function ClassRef:openSetView()
	if self:isViewVisible() then
		UIHandler:handleMessage({id=Constant.FUNC_TYPE_SET, mode="open", data=3})
	end
end

function ClassRef:onOperate(operate, data)
	if operate == "addTarget" then
		app:sendMsg("FriendController", "openView")
	elseif operate == "showNewMsg" then
		--展示新消息
		self:setAutoScrollLock(false)
	elseif operate == "openSetView" then
		self:openSetView()
	elseif operate == "enterWords" then
		local str = string.xmlSpecialChars(data)
		str = string.trim(str)
		self:enterWords(str)
	elseif operate == "wordsChange" then
		self:wordsChange(data)
	end
end

function ClassRef:onBoxSwitch(boxType, scrollView)
	local datas = self._model:getChatBoxData(boxType)
	if boxType == 1 then
		scrollView:showDataList(datas, 0, function(render)
			if render:getData() then
				self:appendWords(render:getData().text)
			end
		end)
	else
		scrollView:showDataList(datas, 0, function(render)
			if render.setSelected then
				render:setSelected(false)
			end
			if render:getData() then
				local shareData = render:getData():getShareData()
				self:appendWords(shareData.textShow, shareData.textSend, shareData.replace)
			end
		end)
	end
end

function ClassRef:openFloatTip(param, posX, posY)
	assert(param ~= nil and type(param) == "table", "IMRoomController.openFloatTip param can't be nil")
	app:dispatchCustomEvent("EVENT_OPEN_FLOAT", {params=param})
end

function ClassRef:onClickLink(url, message, param)
	--print("IMRoomController:onClickLink url = " .. url)
	if not self:isViewAlive() then return end
	local ary = string.split(url, "|")
	if ary[1] == "audio" then
		if ary[2] == "play" then
			if self._voicePlayRender == param then
				-- 已经在播放的render，停止播放
				self:stopPlay()
			else
				self._autoPlayMsgCache = {}
				self:startPlay(message, param)
			end
		elseif ary[2] == "download" then
			self:fetchAttach(message, param)
		end
	elseif ary[1] == "e" then
		--装备
		if ary[3] and ary[4] then
			-- ary[3] 是player.uid, ary[4] 是equip.uid
			self._model:queryUserDetail({who=tonumber(ary[3]), what="equip", uid=ary[4]})
		else
			--不需要显示详细信息的装备
			local param = {
				itemId=tonumber(ary[2]),
				tipsType=Enums.TipsType.equip,
				showPreviewBtn=true
			}
			self:openFloatTip(param)
		end
	elseif ary[1] == "m" then
		local mount = Mount.new()
		mount:read({
				uid=ary[2],
				tid=tonumber(ary[2]),
				levelID=tonumber(ary[3]),
				starID=tonumber(ary[4])
			})
		local param = {
			itemId=tonumber(ary[2]),
			tipsType=Enums.TipsType.mount,
			dataTemp=mount,
			showPreviewBtn=true
		}
		self:openFloatTip(param)
	elseif ary[1] == "q" then
		-- do nothing
	elseif ary[1] == "t" then
		--组队
		local info = message:getSenderInfo()
        local isMe = UD:isMe(info.uid) 
        local targetId = message:getTeamTargetId()       
        if not isMe then --不是自己发的招募信息，判断加入的队伍是否已经更换目标，如果是表示这条招募信息已过期
            app:sendMsg("TeamModel", "reqApplyJoinTeam", info.uid, targetId)
        end
	elseif ary[1] == "i" then
		--道具
		local param = {
			itemId=tonumber(ary[2]),
			tipsType=Enums.TipsType.item,
			showPreviewBtn=true
		}
		self:openFloatTip(param)
	elseif ary[1] == "j" then
		--珠宝
		local param = {itemId=tonumber(ary[2]), tipsType=Enums.TipsType.jewel}
		self:openFloatTip(param)
	elseif ary[1] == "z" then
		--时装
		local param = {itemId=tonumber(ary[2]), tipsType=Enums.TipsType.fashion,showPreviewBtn=true}
		self:openFloatTip(param)
	elseif ary[1] == "h" then
		--随从
		local partner = Partner.new()
		partner:initWithId(tonumber(ary[2]))
		local param = {
			itemId=tonumber(ary[2]),
			tipsType=Enums.TipsType.partner,
			dataTemp=partner,
			showPreviewBtn=true
		}
		self:openFloatTip(param)
	elseif ary[1] == "a" then
		--成就
		local param = {itemId=tonumber(ary[2]), tipsType=Enums.TipsType.achieve, status = checknumber(ary[3])}
		self:openFloatTip(param)
	elseif ary[1] == "o" then
		--船长室
		-- local param = {itemId=tonumber(ary[2]), tipsType=Enums.TipsType.captainRoom}
		-- self:openFloatTip(param)
		app:sendMsg("CaptainController", "openCaptainView", tonumber(ary[2]))
		self:hideView()
	elseif ary[1] == "d" then
		--决斗塞
		print("duel immessage uid", ary[2])
		self:hideView()
	elseif ary[1] == "p" then
		--发送者／接受者
		local info
		if ary[2] == "target" then
			info = message:getTargetInfo()
		elseif ary[2] == "sender" then
			info = message:getSenderInfo()
		end
		UIHandler:showHeadMenu({attr=info, pos=param})
	elseif ary[1] == "u" then
		-- user 内容中的其他玩家link，先把玩家的 userInfo 拉取回来，然后观察的时候直接用
		app:sendMsg("PlayerModel", "reqOtherBaseInfo", tonumber(ary[2]), function(attr, userInfo)
			if attr then
				UIHandler:showHeadMenu({attr=attr, pos=param, userInfo=userInfo})
			end
		end)
	elseif ary[1] == "g" then
		-- 公会招募宣言
		app:sendMsg("NewguildModel", "reqApplyGuild", ary[2]) -- 点击申请加入公会
	end

	self._view:hidePanel()
end

function ClassRef:_refreshMsgList(msgs)
	-- print("IMRoomController._refreshMsgList")
	if not msgs then
		if self._curChannelIdx == 6 then
			local uid = self._curTarget and self._curTarget.uid or nil
			msgs = self._model:getChannelData(self._curChannelIdx, nil, uid)
		else
			msgs = self._model:getChannelData(self._curChannelIdx)
		end
	end
	local index = 0
	local listView = self._view:getMsgList()
	for i,msg in ipairs(msgs) do
		if self:isShowMessage(msg) then --综合频道需要判断信息是否显示
			local render = listView:createRender(index+1)
			render:onClickLink(handler(self, self.onClickLink))
			render:setData(msg)
			index = index + 1
		end
	end

	--删掉多余的item
	self._view:removeUnusedItem(index)
	self._view:jumpToNew()
	
	--通知主界面聊天面板切换频道
	app:sendMsg("IMSimpleController", "switchChannel")
end

function ClassRef:onChannelSwitch(channelIdx, listView)
	--stop voice played render
	self:setVoicePlayRender(nil)
	self._appendMsgCache = nil
	self:setAutoScrollLock(false)

	self._curChannelIdx = channelIdx
	self._model:setCurChannelIdx(self._curChannelIdx)
	self:refreshTargets()
	self:_refreshMsgList()
end

function ClassRef:_recvP2pMsg(msg)
	local isCurChannel = false
	local target = msg:getP2pInfo()

	if not self._curTarget then
		-- 没有聊天对象，直接添加对象
		self._curTarget = target

		-- 直接刷新对象msgs，不需要再设置isCurChannel=true
		self:insertPriTarget(target)
		isCurChannel = false
	else
		if target.uid == self._curTarget.uid then
			-- 是当前聊天对象
			isCurChannel = true
		else
			-- 还没有聊天过，添加一个，已经在聊的添加新消息计数
			local listView = self._view:getPriList()
			local items = listView:getItems()
			local render
			for i,item in ipairs(items) do
				if item:getData() and item:getData().uid == target.uid then
					render = item
					break
				end
			end

			if render then
				render:setNum(self._model:getNewMessageNumFormId(target.uid))
			else
				self:insertPriTarget(target, #items)
			end
		end
	end
	return isCurChannel
end

-- channelIdx = 1 综合
-- channelIdx = 2 世界
-- channelIdx = 3 队伍
-- channelIdx = 4 工会
-- channelIdx = 5 附近(当前地图)
-- channelIdx = 6 蜜语
-- channelIdx = 7 组队?(search)
-- channelIdx = 8 系统
function ClassRef:isMsgInCurChannel(msg)
	local isCurChannel
	local isP2p = msg.sessionType == im.SessionType.P2p
	if self._curChannelIdx == 1 then
		-- isCurChannel = msg.channelId ~= "teamreq" and not isP2p
		--isCurChannel = msg.channelId ~= "teamreq"
        isCurChannel = true
	elseif self._curChannelIdx == 2 then
		isCurChannel = msg.channelId == "world"
	elseif self._curChannelIdx == 3 then
		isCurChannel = msg.channelId == "team"
	elseif self._curChannelIdx == 4 then
		isCurChannel = msg.channelId == "guild"
	elseif self._curChannelIdx == 5 then
		isCurChannel = msg.channelId == "map"
	elseif self._curChannelIdx == 6 then
		isCurChannel = isP2p and self:_recvP2pMsg(msg)
	elseif self._curChannelIdx == 7 then
		isCurChannel = msg.channelId == "teamreq"
	elseif self._curChannelIdx == 8 then
		isCurChannel = msg.channelId == "system"
	end
	return isCurChannel
end

function ClassRef:isShowMessage(msg)
	local isShow = false
	if self._curChannelIdx ~= 1 or (self._curChannelIdx == 1 and msg.showFlag == true) then
		isShow = true
	end
	return isShow
end

function ClassRef:appendNewMsg(msg)
	-- print("IMRoomController.appendNewMsg")
	if self:isMsgInCurChannel(msg) and self:isShowMessage(msg) then
		local render = self._view:addNewMsgItem()
		render:setData(msg)
		render:onClickLink(handler(self, self.onClickLink))
	end
end
function ClassRef:addAppendMsgCache(msg)
	-- print("IMRoomController.addAppendMsgCache")
	if self:isMsgInCurChannel(msg) and self:isShowMessage(msg) then
		self._appendMsgCache = self._appendMsgCache or {}
		table.insert(self._appendMsgCache, msg)
		self._view:refreshNewMsg(#self._appendMsgCache)
	end
end

function ClassRef:teamChanged()
	if cc.isDead(self._view) then return end
	if self._curChannelIdx == 3 then
		self:refreshTargets()
	end
end

function ClassRef:guildChanged()
	if cc.isDead(self._view) then return end
	if self._curChannelIdx == 4 then
		self:refreshTargets()
	end
end

function ClassRef:_onPriTargetClick(render)
	render:setNum(0)	
	self._view:setPriRender(render)
	self._curTarget = render:getData()
	self._model:setCurP2PTarget(self._curTarget)
	self:_refreshMsgList()
	-- 私聊小红点
	self._model:removeP2PMessage(self._curTarget.uid)
end

function ClassRef:insertPriTarget(target, idx)
	-- 插入一个目标，已有的需要移到第一个位置
	idx = idx or 0
	local listView = self._view:getPriList()
	local items = listView:getItems()
	local render
	local foundIdx
	if idx < #items then
		for i,item in ipairs(items) do
			if item:getData() and item:getData().uid == target.uid then
				render = item
				if i ~= 1 then
					render:retain()
					listView:removeItem(i-1)
				end
				foundIdx = i
				break
			end
		end
	end

	if render then
		if foundIdx ~= 1 then
			listView:insertCustomItem(render, idx)
			render:release()
		end
	else
		render = listView:insertRender(0)
	end
	render:onClick(handler(self, self._onPriTargetClick))
	render:setData(target)
	render:setNum(self._model:getNewMessageNumFormId(target.uid))
	if idx == 0 then
		self:_onPriTargetClick(render)
	end
end

function ClassRef:refreshPriTargets(targets)
	local listView = self._view:getPriList()
	local curRender
	for i,v in ipairs(targets) do
		local render = listView:createRender(i)
		render:onClick(handler(self, self._onPriTargetClick))
		render:setData(v)
		render:setNum(self._model:getNewMessageNumFormId(v.uid))
		if self._isSpeakToTarget and self._model:isLastSelectedTarget(v) then -- 不是主动聊天and是上次选中的私聊对象
			curRender = render
		elseif i == 1 then --如果上次没有选中的私聊对象默认选中第一个
			curRender = render
		end
	end
	display.removeListUnuseItem(listView, #targets)
	listView:jumpToLeft()

	if curRender then
		self._isSpeakToTarget = false
		self:_onPriTargetClick(curRender)
	end
end

function ClassRef:refreshTargets()
	local targets = self._model:getTargetList(self._curChannelIdx)
	self._curTarget = targets[1]
	-- dump(self._curTarget, "IMRoomController._curTarget")
	if not self:isViewAlive() then return end

	local isOk = false
	local tips = nil
	local channelName
	local target = self._curTarget
	if self._curChannelIdx == 6 then
		-- 私聊
		if target then
			isOk = true
		else
			tips = L("lua_code_text_254")
		end
	else
		if target == nil then
			tips = L("lua_code_text_426")
		else
			if target.uid == nil then
				if target.roomId == "team" then
					tips = L("tips_1150010")
				elseif target.roomId == "guild" then
					tips = L("tips_1150011")
				else
					tips = L("lua_code_text_230")
				end
			else
				if target.roomId == "world" then
					local isOpen, openLv = self._model:isWorldOpen()
					isOk = isOpen
					if not isOpen then
						tips = string.format(L("tips_1090004"), openLv)
					end
				else
					isOk = true
				end
			end
		end
	end

	local channelName = self._model:getChannelName(self._curChannelIdx)
	self._view:refreshTargets(channelName, isOk, tips)

	if self._curChannelIdx == 6 then
		self:refreshPriTargets(targets)
	end
end

function ClassRef:checkTargetOK(target)
	target = target or self._curTarget
	if target == nil then return false end
	if target.uid == nil then
		if target.roomId == "team" then
			display.pushToast(L("tips_1150010"))
		elseif target.roomId == "guild" then
			display.pushToast(L("tips_1150011"))
		elseif target.sessionType == im.SessionType.P2p then
			display.pushToast(L("tips_1150012"))
        elseif target.roomId == "teamreq" then --组队招募
            return true
		end
	end
	return target.uid ~= nil
end

function ClassRef:sendTextMessage(text, target)
	-- if not self:isViewAlive() then return end
	if not self:checkTargetOK(target) then return end

	target = target or self._curTarget

	local params = {}
	params.sessionType = target.sessionType
	params.uid = target.uid
	params.messageType = im.MessageType.Text
	params.text = text
	params.roomId = target.roomId

	local succ = self._model:sendMessage(params)
	if succ then
		self._textReplaceDict = {}
		self._textRemoveDict = {}
		if self._view ~= nil then
			self._view:clearWords()
		end
	end

	if target.roomId == "system" then
		-- TEST client order
		local commands = app:getCommands()
		if commands then
			for k, func in pairs(commands) do
				if string.isStartWith(text, k) then
					executeFunc(func, text)
					break
				end
			end
		end

		if DEBUG > 0 and text ~= L(text) then
			self._model:addSystemMsg(L(text))
		end
		if DEBUG > 0 then
			local list = {}
			table.insert(list, {content = text, priority = 999})
			app:sendMsg("UIController", "showRollNotice", list)
		end
	end
end

function ClassRef:sendAudioMessage(param, target)
	if not self:checkTargetOK(target) then return end

	target = target or self._curTarget

	local params = {}
	params.sessionType = target.sessionType
	params.uid = target.uid
	params.messageType = im.MessageType.Text

	local duration = math.ceil(param.duration * 10)/10
	local ary = {"[v", L("lua_code_text_342"), param.fileId, duration.."]"}
	local text = table.concat(ary, "|") .. param.audioText
	params.text = text
	params.roomId = target.roomId

	self._model:sendMessage(params)
end

function ClassRef:appendWords(textShow, textSend, replace)
	if textSend then
		for k,v in pairs(self._textReplaceDict) do
			if v.uniq == textSend then
				-- print("一个道具只需要展示一次")
				return
			end
		end

		-- 多个相同名字的道具 在名字后面添加数字区分 如：[大锤][大锤1][大锤2]
		local text = string.sub(textShow, 2, -2)
		local index = 0
		while self._textReplaceDict[textShow] do
			index = index + 1
			textShow = "[" .. text .. index .. "]"
		end

		local textUniq = textSend
		if index > 0 then
			textSend = string.gsub(textSend, text, text .. index)
		end
		self._textReplaceDict[textShow] = {send=textSend, uniq=textUniq, replace=replace}
	end
	self._view:appendWords(textShow)
end

function ClassRef:wordsChange(text)
	if string.len(text) > 0 then
		for k,v in pairs(self._textReplaceDict) do
			local split = "%[" .. string.sub(k, 2, -2) .. "%]"
			if string.find(text, split) == nil then
				self._textReplaceDict[k] = nil
				self._textRemoveDict[k] = v
			end
		end
	end
end

function ClassRef:enterWords(showText)
	-- dump(self._textReplaceDict, "enterWords:_textReplaceDict")
	-- dump(self._textRemoveDict, "enterWords:_textRemoveDict")
	local function getSendText(key)
		return self._textReplaceDict[key] or self._textRemoveDict[key]
	end

	local sendText = showText

	local function replaceText(k, v)
		-- 如果玩家手动有修改 [大锤][大锤1][大锤2] ＝》 [大锤][大锤][大锤]
		-- or 如果玩家手动有修改 [大锤][大锤1][大锤2] ＝》 [大锤][大锤1][大锤1]
		-- 自动替换回 [大锤][大锤1][大锤2]

		local key = string.luaSpecialChars(k)
		local split = "(" .. key .. ")"
		local index = 0
		sendText = string.gsub(sendText, split, function(catch)
			index = index + 1
			local ret
			if index == 1 then
				ret = v
			else
				local chars = string.sub(k, 2, -2)
				local lastChar = tonumber(string.sub(chars, -1, -1))

				if type(lastChar) == "number" then
					local newKey = "[" .. string.sub(chars,1, -2) .. (lastChar+1) .. "]"
					ret = getSendText(newKey)
				end
				ret = ret or getSendText("[" .. chars .. (index-1) .. "]") or v
			end

			local send = ret.send
			local pre = string.sub(send, 1, 3)
			-- 道具和配方，去掉里面的uid再发送
			if pre == "[i|" or pre == "[c|" then
				send = string.gsub(send, "(|[^|]+%])", "]")
			end
			if ret.replace then
				local reg = string.luaSpecialChars(ret.replace[1])
				local sIdx, eIdx = string.find(send, reg)
				if sIdx then
					local nextChar = string.sub(send, eIdx+1, eIdx+1)
					if nextChar == "|" or nextChar == "," then
						send = string.gsub(send, reg, ret.replace[2])
					else
						send = string.gsub(send, reg, ret.replace[2]..";")
					end
				end
			end
			return send
		end)
	end

	for k, v in pairs(self._textReplaceDict) do
		replaceText(k, v)
	end
	for k, v in pairs(self._textRemoveDict) do
		replaceText(k, v)
	end

	-- self._textReplaceDict = {}
	-- self._textRemoveDict = {}
	-- print("showText = " .. showText)
	-- print("sendText = " .. sendText)

	self:sendTextMessage(sendText, nil)
end

function ClassRef:fetchAttach(message, render)
	self:setVoicePlayRender(render)
	self._model:fetchAttach(message)
end

function ClassRef:onFetchAttachmentComp(msg)
	-- 手动点击下载之后必定自动播放
	if not tolua.isnull(self._voicePlayRender) and self._voicePlayRender:getData().messageId == msg.messageId then
		-- print("IMRoomController.onFetchAttachmentComp() manual play")
		self._autoPlayMsgCache = {}
		self:startPlay(msg, self._voicePlayRender)
		return
	end

	-- 不能播放说明拉取附件失败，不添加到自动播放
	if not msg:isCanPlay() then return end

	local auto
	if msg.channelId == "world" then
		auto = UD.setting:isAutoPlayAudioWorld()
	elseif msg.channelId == "guild" then
		auto = UD.setting:isAutoPlayAudioGuild()
	elseif msg.channelId == "team" then
		auto = UD.setting:isAutoPlayAudioTeam()
	end

	if auto then
		-- print("IMRoomController.onFetchAttachmentComp() auto play")
		table.insert(self._autoPlayMsgCache, msg)
		if not im.isPlaying then
			self:setVoicePlayRender(nil)
			self:autoPlayAudio()
		end
	end
end

function ClassRef:autoPlayAudio()
	-- 如果开启组队实时语音 停止自动播放
	-- print("IM.autoPlayAudio")
	local need = app:sendMsg("IMRecordController", "needBackToRealtime")
	if need then
		self._autoPlayMsgCache = {}
	end

	if #self._autoPlayMsgCache > 0 then
		-- print("IMRoomController.autoPlayAudio()")
		local nextMsg = self._autoPlayMsgCache[1]
		local render
		if self:isViewVisible() then
			local items = self._view:getMsgItems()
			for i,item in ipairs(items) do
				if item:getData() and item:getData().messageId == nextMsg.messageId then
					render = item
					break
				end
			end
		end
		table.remove(self._autoPlayMsgCache, 1)
		self:startPlay(nextMsg, render)
	end
end

function ClassRef:setVoicePlayRender(render)
	if not tolua.isnull(self._voicePlayRender) then
		self._voicePlayRender:stopVoiceAction()
	end
	self._voicePlayRender = render
end

function ClassRef:stopPlay()
	self._model:setModeTranslate()
	im.stopPlay()
	im.isPlaying = false
	-- AM.resumeAll()
	self:setVoicePlayRender(nil)
	self:autoPlayAudio()
end

function ClassRef:startPlay(msg, render)
	-- print("IMRoomController:startPlay() isPlaying = " .. tostring(im.isPlaying))
	if msg:isCanPlay() then
		msg:setIsPlayed(true)

		-- print("im.playAudio")
		self._model:setModeTranslate()
		local code = im.playAudio(msg.audioPath)
		if code == 0 then
			self:setVoicePlayRender(render)
			if not tolua.isnull(self._voicePlayRender) then
				self._voicePlayRender:playVoiceAction()
			end
			im.isPlaying = true
			-- AM.pauseAll()
		else
			self:stopPlay()
		end
	else
		self:stopPlay()
	end
end

function ClassRef:onPlayEnd(succ, filePath)
	self:setVoicePlayRender(nil)
	self:autoPlayAudio()
end

function ClassRef:checkP2PRedPoint(uid)
	local showRedPoint = self._model:isShowP2PRedPoint()
	-- 密聊页签的小红点
	if self:isViewAlive() then
		self._view:setP2PBtnRedPoint(showRedPoint)
	end
	-- 右下角通知
	if showRedPoint then
		local params = {
			remindId = Constant.FUNC_TYPE_CHAT,
			dataTemp = 6, --channelIdx
			uid = uid
		}
		UIHandler:getDesktopController():insertFourthTips( params )
	else
		UIHandler:getDesktopController():removeFourthTipsByType( Constant.FUNC_TYPE_CHAT )
	end
end

return ClassRef
